from flask_mail import Message
from flask import jsonify, session, current_app, g, request
from datetime import datetime, timedelta
from exts import mail, redis_store, db
from models import Users
from api.jwt_api import generate_jwt, verify_jwt
from sqlalchemy.orm import load_only


def generator_token(user_id):
    login_payload = {
        "user_id": user_id,
        "is_refresh": False
    }
    expire_2h = datetime.utcnow() + timedelta(hours=current_app.config["LOGIN_TOKEN_EXPIRE"])
    secret = current_app.config["JWT_SECRET"]
    login_token = generate_jwt(payload=login_payload, expiry=expire_2h, secret=secret)

    refresh_payload = {
        "user_id": user_id,
        "is_refresh": True
    }
    expire_14d = datetime.utcnow() + timedelta(days=current_app.config["REFRESH_TOKEN_EXPIRE"])
    refresh_token = generate_jwt(payload=refresh_payload, expiry=expire_14d, secret=secret)
    return login_token, refresh_token


# 发送一封带有验证码的邮件，将email作为键值，验证码作为value，保存到redis中
def sendEmailCode(code, mailpath):
    try:
        redis_store.set(f"test:user:email:{mailpath}", code, ex=timedelta(seconds=1800))
        message = Message(subject="验证码", recipients=[mailpath], body="注册验证码：{}".format(code))
        mail.send(message)
        return jsonify({'message': '发送成功', 'code': 200})
    except:
        return jsonify({'message': '发送失败，请稍后再试', 'code': 1002})


# 检查用户名是否被注册
def checkUsernameValuable(username):
    i = Users.query.filter_by(name=username).first()
    if i is not None:
        return False
    else:
        return True


# 检查邮箱是否被注册
def checkEmailCanUse(email):
    i = Users.query.filter_by(email=email).first()
    if i is not None:
        return False
    else:
        return True


# 检查验证码是否与缓存中邮箱的内容一致
def checkCodeValid(email, code):
    try:
        i = redis_store.get(f"test:user:email:{email}")
        i = bytes.decode(i)
        if i is None or i != code:
            return False
        else:
            return True
    except:
        pass


def registerNewUser(username, password, email):
    try:
        i = Users(name=username, password=password, email=email, created_at=datetime.datetime.now())
        db.session.add(i)
        db.session.commit()
        return True
    except:
        return False


def checkLogin(username, password):
    try:
        i = Users.query.filter_by(name=username).first()
        if i is not None:
            if i.password == password:
                session['user_id'] = i.id
                g.user_id = i.id
                login_token, refresh_token = generator_token(i.id)
                redis_store.set(f'test:user:token:{i.id}',login_token,ex=timedelta(days=2))
                return jsonify(
                    {'to': '/manager', 'login_token': login_token, 'refresh_token': refresh_token, 'code': 2001})
                # return jsonify({'to': '/manager', 'code': 2001})
            else:
                return jsonify({'message': "密码错误", 'code': 1007})
        else:
            return jsonify({'message': '用户名不存在', 'code': 1006})
    except:
        return jsonify({'message': '未知错误', 'code': 9999})


def put():
    user_id = g.user_id
    is_refresh = g.is_refresh
    if user_id and is_refresh:
        login_token, _ = generator_token(user_id)
        return {"new_token": login_token}
    else:
        return {"message": "wrong refresh token"}, 403


def queryOneUserInfo(user_id):
    if user_id is None:
        return None
    i = Users.query.filter_by(id=user_id).options(load_only(Users.name, Users.email, Users.phone, Users.avatar)).first()
    return {'name': i.name, 'email': i.email, 'phone': i.phone, 'avator': i.avatar}


def userLogout():
    print(g.user_id)
    redis_store.delete(f'test:user:token:{g.user_id}')
    g.user_id = None
    g.is_refresh = True
    return None